package cn.cloudtogo.common.util;

import cn.cloudtogo.common.GendbException;
import cn.cloudtogo.common.model.ExternalDatasourceModel;
import cn.cloudtogo.common.types.RequestHeaderObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;

import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;

/**
 * @author yaolianhua789@gmail.com
 **/
@Slf4j
public final class StringHelper {

    private StringHelper() {
    }

    public static Map<String, String> parseParam(String url) {
        if (!StringUtils.hasText(url)) {
            return Map.of();
        }
        String[] urlParts = url.split("\\?");
        if (urlParts.length == 1) {
            return Map.of();
        }
        String[] params = urlParts[1].split("&");

        Map<String, String> map = new HashMap<>(16);
        for (String param : params) {
            String[] keyValue = param.split("=");
            map.put(keyValue[0], keyValue[1]);
        }
        return map;

    }

    public static String encode(String delimiter, String[] args) {

        boolean matchNull = Stream.of(args).anyMatch(e -> !StringUtils.hasText(e));
        if (matchNull) {
            throw new GendbException("parameters contains null");
        }

        if (!StringUtils.hasText(delimiter)) {
            delimiter = "|";
        }
        String key = String.join(delimiter, args);

        return Base64.getEncoder().encodeToString(key.getBytes());

    }

    public static String decode(String base64) {
        try {
            return new String(Base64.getDecoder().decode(base64));
        } catch (Exception e) {
            throw new GendbException("invalid key");
        }

    }

    public static String pretty(RequestHeaderObject requestHeaderObject, String action, String table, Object obj) {
        ExternalDatasourceModel model = RequestHeaderObject.extractExternalDatasourceModel(requestHeaderObject);
        StringBuilder sb = new StringBuilder();
        sb.append("\n");
        sb.append("###################################################################\n");
        sb.append("Action: ").append(action).append("\n");
        sb.append("Project: ").append(model.getProject()).append("\n");
        sb.append("Name: ").append(model.getName()).append("\n");
        sb.append("Url: ").append(model.getUrl()).append("\n");
        sb.append("Openid: ").append(model.getOpenid()).append("\n");
        sb.append("Schema: ").append(model.getSchema()).append("\n");
        sb.append("Table: ").append(table).append("\n");
        ObjectMapper objectMapper = new ObjectMapper();
        String valueAsString;
        if (obj instanceof String) {
            valueAsString = String.format("%s", obj);
        } else {
            try {
                valueAsString = objectMapper.writeValueAsString(obj);
            } catch (JsonProcessingException e) {
                valueAsString = String.format("An error occurred [%s]", e.getMessage());
            }
        }
        sb.append("Param: ").append(valueAsString).append("\n");
        sb.append("###################################################################\n");
        return sb.toString();
    }

    public static String hasTextOrDefault(String text, String defaultValue) {
        return StringUtils.hasText(text) ? text : defaultValue;
    }

}
